/**
 * 
 */
package nl.boektrust.btsoep.shared.model;

import java.io.Serializable;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;


import com.google.gwt.user.client.rpc.IsSerializable;

/**
 * @author rao3
 *
 */
public class ISBN implements IsSerializable,Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -6047563159303168231L;
	private String isbn12 = new String("");

	/**
	 * @param isbn12; may be a 12 or 13 character ISBN; if it is a 13 character ISBN, the last character (control character) is removed and ignored. 
	 * throws Exception e = if the ISBN is not a valid ISBN12 or ISBN13
	 */
	public ISBN(String isbn12) {
		super();
		//this.isbn12 = new String("9789062623310");
		try {
			if (isbn12 != null) {
				this.setIsbn12(isbn12);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public ISBN()  {
		this("");
	}
	/**
	 * @return the isbn12
	 */
	public String getIsbn12() {
		return this.isbn12;
	}

	/**
	 * @param isbn12 the isbn12 to set
	 */
	public void setIsbn12(String isbn12) throws Exception {
		try {
			if (isbn12.length() > 12) isbn12 = isbn12.substring(0, 12); 
		} catch (Exception e) {
			System.err.println("ISBN:setIsbn12(): error, isbn12.substring(0,12) threw an error, value of isbn12: "+isbn12);
		}
/*		if (ISBN.isValidISBN13(isbn12) == false) {
			throw new Exception("invalid isbn13: "+isbn12);
		}
		*/
		this.isbn12 = new String(isbn12);

	}
	
	
	/**
	 * instance method to check if the isbn12 in this instance is a valid ISBN13 prefix. 
	 * @return true or false
	 */
	public boolean isValidISBN13() {
		return ISBN.isValidISBN13(this.getIsbn12());
	}
	
	/**
	 * tests to see if isbn is a valid ISBN13. Tests for appropriate length (12 or 13 characters), for all-digits and for a valid control char, if 13 characters long.  
	 * @param isbn
	 * @return true or false
	 */
	
	public static boolean isValidISBN13(String isbn) {
		// test for length
		if (!(isbn.length() == 12 || isbn.length() == 13)) {
			return false;
		}
		// check that there are only digits in the ISBN
		for (int i=0; i<isbn.length(); i++) {
			if (Character.isDigit(isbn.charAt(i))==false) return false;
		}
		if (isbn.length() == 13) {
			if (isbn.charAt(12) != ISBN.computeControlChar(isbn)) return false;
		}
		return true;
	}
	
	/**
	 * computes the control character of any ISBN12 or ISBN13 string. 
	 * @param isbn the isbn to compute the control character for. May be 12 or 13 characters long. 
	 * @return the computed control character, or 'X' if the isbn is not 12 or 13 characters long, or contains invalid characters 
	 */
	
	public static  char computeControlChar(String isbn) {
		int s=0;
		// test for length
		try {
			if (!(isbn.length() == 12 || isbn.length() == 13)) {
				return 'X';
			}
		
		// check that there are only digits in the ISBN
		for (int i=0; i<12; i++) {
			if (Character.isDigit(isbn.charAt(i))==false) return 'X';
		}
		} catch (Exception e) {
			System.err.println("ISBN:computeControlChar:exception thrown");
			e.printStackTrace();
		}
		char[] digit = new char[1];
		Integer num;
		for (int i=0; i<12; i+=2) {
			digit[0] = isbn.charAt(i);
			num = new Integer(new String(digit));
			s += 1*num;
			digit[0] = isbn.charAt(i+1);
			num = new Integer(new String(digit));
			s += 3*num;
		}
		int controlChar = 10-(s % 10);
		if (controlChar == 10) controlChar = 0;
		return new Integer(controlChar).toString().charAt(0);
	}
	
	
	/**
	 * @return a valid isbn13 generated from the stored isbn12 + the control char. 
	 */
	
	public String getIsbn13() {
		if (this.getIsbn12() == null) {
			return null;
		}
		if (this.getIsbn12().length() == 0) {
			return "";
		}
		if (this.getIsbn12().length() < 12) {
			return null;
		}
		return this.getIsbn12()+ISBN.computeControlChar(this.getIsbn12());
	}
	
	

}


